<?php

// | Copyright (c) 2019~2020 http://jiunidu.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: huanglijun <80792275@qq.com>
// +----------------------------------------------------------------------

namespace service\pay;


use app\common\model\CouponCode;
use app\group\model\GroupOrderModel;
use app\funding\model\FundingOrder;
use app\order\model\Order;
use think\Exception;
use think\facade\Log;
use think\facade\Request;
use service\tools\http\Curl;
use service\pay\WxPay;
use service\pay\PayDb;
use think\facade\Env;
use service\pay\VirtualPay;
use app\activity\model\RefundcoModel;
use app\property\model\PropertySubscribe;
use service\Distribution;
use service\OrderReturnService;
use app\decoration\model\RefundModel;
use app\common\model\CoreOrderService;
use app\common\model\CoreOrder;

class PayServiceNew
{

    //支付对象
    protected $pay=null;
    //支付回调
    protected $pay_notify_url          =   "/pay_notity";
    //退款支付回调
    protected $refund_notify_url       =   "/refund_notity";

    public function __construct()
    {
        $this->pay_notify_url       =   Env::get('app.callback_host').$this->pay_notify_url;
        $this->refund_notify_url    =   Env::get('app.callback_host').$this->refund_notify_url;
    }

    //订单类型  1 商品 2 拼团 3 众筹 4 活动 5 装修 6 线下购 7线上预约 8 楼盘认筹
    protected $order_type_body=[
                                '1'=>"商品",
                                '2'=>"拼团",
                                '3'=>"众筹",
                                '4'=>"活动",
                                '5'=>"装修",
                                '6'=>"线下购",
                                '7'=>"线上预约",
                                '8'=>'楼盘认筹',
                               ];
    //各订单，处理支付回调的方法模型
    protected $pay_notity_url=[
                                '1'=>"OrderModel",
                                '2'=>"拼团",
                                '3'=>"众筹",
                                '4'=>"活动",
                                '5'=>"装修",
                                '6'=>"线下购",
                                '7'=>"线上预约",
                                '8'=>"楼盘认筹",
                               ];
    //返回的数据格式1000：表示成功，其他表示失败，message提示的信息,$data,返回的数据数组
    public $return_ok=['code'=>1000,'message'=>"操作成功",'data'=>[]];
    public $return_fail=['code'=>2000,'message'=>"操作失败",'data'=>[]];


    /**
     * 生成退款记录
     *
     * @param int $refund_id            退订(售后)订单号
     * @return bool                     是否成功
     */
    public function CreateRefund($refund_id='')
    {
        Log::info('RefundNotify backend:createRefund');
        if(empty($refund_id))
        {
            $this->return_fail['message']='必填字段为空!';
            return false;
        }
        $this->return_ok['data']['wxpay_params']=(object)array();
        $pay_db=new PayDb();


        /** 获取售后订单数据 */
        $order_service=new CoreOrderService();
        $order_data=$order_service->getOneBySn($refund_id);
        if(empty($order_data))
        {
            $this->return_fail['message']='售后订单错误!';
            return false;
        }

        //获取用户信息
        $user_info=$pay_db->get_user_info($order_data['user_id'],"user_wx_openid,user_balance,user_gold,user_pay_psw");
        if(empty($user_info))
        {
            $this->return_fail['message']='用户信息错误';
            return false;
        }


        //获取支付信息
        $pay_info=$pay_db->get_pay_info($order_data['order_sn'],"payed,pay_fee,coin_fee,balance_fee,remark");
        if(!empty($pay_info))
        {
            if($pay_info['payed']!==2)
            {
                $this->return_fail['message']='此订单不可以退款!';
                return false;
            }
            //获取退款信息
            $refund_info=$pay_db->get_refund_info($order_data['order_sn'],$refund_id,"refunded");
            if(!empty($refund_info))
            {
                if($refund_info['refunded']==2)
                {
                    $this->return_fail['message']='此订单的退款订单号已经退款了';
                    return false;
                }
            }

        }
        
        $order_type = $order_data['order_type'];
        $order_id = $order_data['order_sn'];

        //入库处理
        $data['order_id']=$order_data['order_sn'];
        $data['refund_id']=$refund_id;
        $data['user_id']=$order_data['user_id'];
        $data['refunded']=1;
        $data['order_type']=$order_data['order_type'];
        /** 第三方支付 */
        $data['refund_pay_fee']= $order_data['money'];
        /** 金币支付 */
        $data['refund_coin_fee']=$order_data['gold_coin'];
        /** 余额支付 */
        $data['refund_balance_fee']=$order_data['balance'];
        $data['add_time']=time();
        $data['update_time']=time();
        $data['remark']=$order_data['remark'];
        
        $return_id=$pay_db->update_refund_data($data);
        //Log::info("return_id:" . $refund_id);die;
        
        if((int)$return_id<=0)
        {
            //处理成功后返回
            return false;
        }

        // 优惠券返还
        //$this->returnCoupon($order_id);
        
        //使用了第三方支付
        if($order_data['money']>0)
        {
            $core_order = new CoreOrder();
            $core_data = $core_order->getOneBySn($order_data['order_sn']);

            if (!empty($core_data['parent_order'])) {
                $parent_data = $core_order->getOneBySn($core_data['parent_order']);
                $order_sn = $core_data['parent_order'];
                $order_money = bcsub($parent_data['amount_pay'], $parent_data['balance'], 2) * 100;
            } else {
                $order_sn = $order_data['order_sn'];
                $order_money = bcsub($core_data['amount_pay'], $core_data['balance'], 2) * 100;
            }

            Log::info('RefundNotify backend:third pay');
            //Log::info('第三方');
            $this->pay=new WxPay();
            $this->pay->refund_notify_url=$this->refund_notify_url;
            $this->pay->open_id=$user_info['user_wx_openid'];
            //保存订单类型，回调方便分发回调信息
            $this->pay->attach=$order_type;
            $this->pay->setOrderBody($this->order_type_body[$order_type]);
            $this->pay->setPayFee($order_money);
            $this->pay->setRefundFee($order_data['money']);
            $this->pay->setOrderId($order_sn);
            $this->pay->setRefundId($refund_id);
            // $this->pay->set_pay_platform($pay_platform);
            //微信预付款ID
            $yesno_refund=$this->pay->unifiedOrderRefund();
            Log::info("微信退款".print_r($yesno_refund,true));
            if($yesno_refund) return true;

        }
        //没有使用第三方支付
        if($order_data['money']==0)
        {
            Log::info('RefundNotify backend:self pay');
            //Log::info('余额支付');
          //余额支付通知
          $yesno_refund=$this->RefundNotity(1,1,$order_type,$order_id,$refund_id);
          //Log::info('returnNotify result:' . $yesno_refund);
          Log::info("余额退款".print_r($yesno_refund,true));
          if($yesno_refund) return true;
        }

        return false;
    }
    
   
    
    /**
     * 获取回调基本数据
     */
    public function getPayBaseData($order_id='')
    {
        $return_array=[];
        if(empty($order_id))
        {
            return $return_array;
        }
        //获取支付信息
        $pay_db=new PayDb();
        $return_array=$pay_db->get_pay_info($order_id,"order_id,user_id,pay_fee,coin_fee,balance_fee,remark");
        return $return_array;
    }
    /**
     * 获取退款回调基本数据
     */
    public function getRefundBaseData($order_id='',$refund_id='')
    {
        $return_array=[];
        if(empty($order_id) || empty($refund_id))
        {
            return $return_array;
        }
        //获取支付信息
        $pay_db=new PayDb();
        $return_array=$pay_db->get_refund_info($order_id,$refund_id,"order_id,user_id,refunded,refund_id,refund_pay_fee,refund_coin_fee,refund_balance_fee,remark");
        return $return_array;
    }
    /**
     * 支付回调处理
     */
    public function PayNotity($pay_platform=0,$yesno=0,$order_type=0,$order_id=0)
    {
        $return_notity=false;
        $notity_data=['base_data'=>[],'other_data'=>[]];
        $pay_type=0;
        Log::info("余额支付:".$pay_platform.$order_type.$order_id.$yesno);
        //处理微信回调
        if($pay_platform==1)
        {
            $yesno=1;
            $pay_type=1;
            $base_data=$this->getPayBaseData($order_id);
            $notity_data['base_data']=$base_data;
            $notity_data['other_data']=[];
        }
        //处理微信回调
        if($pay_platform==2)
        {
            $this->pay=new WxPay();
            //验证签名信息
            $yesno=$this->pay->check_notify_sign();
            //验证成功,分发回调数据到具体业务逻辑
            Log::info("微信回调签名结果".$this->pay->notice_result_msg);

            if($yesno==true)
            {
                Log::info("微信回调数据数组".print_r($this->pay->request_data,true));
                $yesno=1;
                $pay_type=2;
                $base_data=$this->getPayBaseData($this->pay->request_data['out_trade_no']);
                if(empty($base_data))
                {
                    $yesno=2;
                }
                $notity_data['base_data']=$base_data;
                $notity_data['other_data']=$this->pay->request_data;
                $order_type=$this->pay->request_data['attach'];
                Log::info("平台回调数据数组".print_r($notity_data,true));
                //判断是否需要调用平台支付系统，平台目前优先余额、金币强制全额支付
                //平台支付系统成功，把成功信息分发到业务，如果失败，分发错误信息
                //具体业务逻辑处理成功，则返回微信成功信息
                $pay_type=0;
                if($base_data['balance_fee']>0)
                {
                    $pay_type=1;
                    $balance_fee=bcdiv($base_data['balance_fee'],100,2);     
                }
                if($base_data['coin_fee']>0)
                {
                    $pay_type=2;   
                    $coin_fee=bcdiv($base_data['coin_fee'],100,2);   
                }
                if($base_data['balance_fee']>0 && $base_data['coin_fee']>0 )
                {
                    $pay_type=3; 
                    $balance_fee=bcdiv($base_data['balance_fee'],100,2); 
                    $coin_fee=bcdiv($base_data['coin_fee'],100,2);
                }

                $virtual_pay=new VirtualPay();
                $return_id=$virtual_pay->update_user_virtual($base_data['user_id'],'',2,$pay_type,$balance_fee,$coin_fee);
                //平台支付失败，分发到业务逻辑失败
                if($return_id==-1)
                {
                    $yesno=2;
                }
            }
            //返回微信错误信息
        }

        //回调分发 订单类型  1 商品 2 拼团 3 众筹 4 活动 5 装修 6 线下购 7线上预约 8 楼盘认筹
        switch ($order_type)
        {
            case 1:
                $order = new Order();
                $return_notity=$order->PayNotity($yesno,$pay_type,$notity_data);
            break;
            case 2:
                $group = new GroupOrderModel();
                $return_notity=$group->PayNotity($yesno,$pay_type,$notity_data);
                
            break;
            case 3:
                $funding = new FundingOrder();
                $return_notity = $funding->PayNotity($yesno,$pay_type,$notity_data);
            break;
            case 4:
                $community = new CommunityModel();
                $return_notity=$community->PayNotity($yesno,$pay_type,$notity_data);
            break;
            case 5:
                $subscribe = new Subscribe();
                $return_notity=$subscribe->PayNotity($yesno,$pay_type,$notity_data);
            break;
            case 6:
                $store_order = new StoreOrder();
                $return_notity=$store_order->PayNotity($yesno,$pay_type,$notity_data);
            break;
            case 7:
                $store_order = new StoreOrder();
                $return_notity=$store_order->PayNotity($yesno,$pay_type,$notity_data);
            break;
            case 8:
                $property_subscribe = new PropertySubscribe();
                $return_notity=$property_subscribe->PayNotity($yesno,$pay_type,$notity_data);
            break;
            default:
            break;
        }
        //业务逻辑处理成功后
        if($return_notity)
        {
            //更新支付成功数据 
            $pay_db=new PayDb();
            $data['payed']=2;
            $data['transaction_id']=empty($this->pay->request_data['transaction_id'])?"":$this->pay->request_data['transaction_id'];
            $pay_db->update_paystatus_data($order_id,$data);
        }
        return $return_notity;
    }
    
    /**
     * 退款回调处理
     */
    public function RefundNotity($pay_platform=0,$yesno=0,$order_type=0,$order_id=0,$refund_id=0)
    {
        $return_notity=false;
        $notity_data=['base_data'=>[],'other_data'=>[]];
        $pay_type=0;
        Log::info("RefundNotity111:余额退款回调".$order_type);
        //处理余额回调
        if($pay_platform==1)
        {
            $yesno=1;
            $pay_type=1;
            $base_data=$this->getRefundBaseData($order_id,$refund_id);
            //Log::info('refund_base_data:', $base_data);
            $notity_data['base_data']=$base_data;
            $notity_data['other_data']=[];

            $pay_type=0;
            $refund_coin_fee=0;
            $refund_balance_fee=0;
             if($base_data['refund_balance_fee']>0)
             {
                 $pay_type=1;   
                 $refund_balance_fee=bcdiv($base_data['refund_balance_fee'],100,2);
             }
             if($base_data['refund_coin_fee']>0)
             {
                 $pay_type=2;     
                 $refund_coin_fee=bcdiv($base_data['refund_coin_fee'],100,2);
             }
             if($base_data['refund_balance_fee']>0 && $base_data['refund_coin_fee']>0 )
             {
                 $pay_type=3; 
                 $refund_balance_fee=bcdiv($base_data['refund_balance_fee'],100,2);
                 $refund_coin_fee=bcdiv($base_data['refund_coin_fee'],100,2);
             }
             Log::info("RefundNotity:余额退款回调66".$refund_balance_fee);
             $virtual_pay=new VirtualPay();
             $return_id=$virtual_pay->update_user_virtual($base_data['user_id'],'',1,$pay_type,$refund_balance_fee,$refund_coin_fee,1,$base_data['order_id'],$base_data['remark']);
             Log::info("RefundNotity:余额退款回调777_".$return_id);
             //平台支付失败，分发到业务逻辑失败
             if($return_id==-1)
             {
                 $yesno=2;
             }
        }

        //处理微信回调
        if($pay_platform==2)
        {
            $this->pay=new WxPay();
            //验证签名信息
            $yesno=$this->pay->check_refund_notify();
            //验证成功,分发回调数据到具体业务逻辑
            Log::info("微信退款回调签名结果".$this->pay->notice_result_msg);

            if($yesno==true)
            {
                Log::info("微信退款回调数据数组".print_r($this->pay->request_data,true));
                $yesno=1;
                $pay_type=2;
                $base_data=$this->getRefundBaseData($this->pay->request_data['out_trade_no'],$this->pay->request_data['out_refund_no']);
                if(empty($base_data))
                {
                    $yesno=2;
                }
                $notity_data['base_data']=$base_data;
                $notity_data['other_data']=$this->pay->request_data;
                $order_type=$this->pay->request_data['attach'];
                Log::info("平台退款回调数据数组".print_r($notity_data,true));
                //判断是否需要调用平台支付系统，平台目前优先余额、金币强制全额支付
                //平台支付系统成功，把成功信息分发到业务，如果失败，分发错误信息
                //具体业务逻辑处理成功，则返回微信成功信息
                $pay_type=0;
                if($base_data['refund_balance_fee']>0)
                {
                    $pay_type=1;
                    $refund_balance_fee=bcdiv($base_data['refund_balance_fee'],100,2);     
                }
                if($base_data['refund_coin_fee']>0)
                {
                    $pay_type=2;     
                    $refund_coin_fee=bcdiv($base_data['refund_coin_fee'],100,2);
                }
                if($base_data['refund_balance_fee']>0 && $base_data['refund_coin_fee']>0 )
                {
                    $pay_type=3; 
                    $refund_balance_fee=bcdiv($base_data['refund_balance_fee'],100,2);
                    $refund_coin_fee=bcdiv($base_data['refund_coin_fee'],100,2);
                }
                if($pay_type!=0)
                {
                    $virtual_pay=new VirtualPay();
                    $return_id=$virtual_pay->update_user_virtual($base_data['user_id'],'',1,$pay_type,$refund_balance_fee,$refund_coin_fee,1,$base_data['order_id'],$base_data['remark']);
                    //平台支付失败，分发到业务逻辑失败
                    if($return_id==-1)
                    {
                        $yesno=2;
                    }
                }
            }
            //返回微信错误信息
        }
        
        Log::info("RefundNotify: order_type:" . $order_type);
         //回调分发 订单类型  1 商品 2 拼团 3 众筹 4 活动 5 装修 6 线下购 7线上预约 8 楼盘认筹
         switch ($order_type)
         {
            case 1:
                $return_service = new OrderReturnService();
                $return_notity = $return_service->RefundNotity($yesno, $pay_type, $notity_data);
                //$order = new Order();
                //$return_notity=$order->RefundNotity($yesno,$pay_type,$notity_data);
            break;
            case 2:
                $group = new GroupOrderModel();
                $return_notity=$group->RefundNotity($yesno,$pay_type,$notity_data);
                Log::info("拼团:".$yesno.$pay_type.print_r($notity_data,true));
            break;
            case 3:
                $funding = new FundingOrder();
                $return_notity = $funding->RefundNotity($yesno,$pay_type,$notity_data);
            break;
            case 4:
                $community = new RefundcoModel();
                $return_notity=$community->RefundNotity($yesno,$pay_type,$notity_data);
            break;
            case 5:
                $subscribe = new RefundModel();
                $return_notity=$subscribe->RefundNotity($yesno,$pay_type,$notity_data);
            break;
            case 6:
                $store_order = new \app\store\model\StoreOrder();
                $return_notity=$store_order->RefundNotity($yesno,$pay_type,$notity_data);
            break;
            case 7:
                $store_order = new \app\store\model\StoreOrder();
                $return_notity=$store_order->RefundNotity($yesno,$pay_type,$notity_data);
            break;
            case 8:
                $property_subscribe = new PropertySubscribe();
                $return_notity=$property_subscribe->RefundNotity($yesno,$pay_type,$notity_data);
            break;
            default:
            break;
         }
         
        //更新退款成功数据 
        $pay_db=new PayDb();
        $data['refunded']=2;
        $data['transaction_id']=empty($this->pay->request_data['transaction_id'])?"":$this->pay->request_data['transaction_id'];
        $pay_db->update_refundstatus_data($order_id,$refund_id,$data);
          //业务逻辑处理成功后

        if($return_notity)
        {
            // //退款完成后，解锁释放冻结的返利的余额、金币
            // $distribution=new Distribution();
            // $distribution->unlock_virtual($order_type,$order_id,2);
        }
         return $return_notity;
    }

}
